home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 10 - 1994 / 10.05 May 94 / SerialEx / SerialProject.text < prev    next >
Encoding:
Text File  |  1994-03-20  |  7.1 KB  |  249 lines  |  [TEXT/MPS ]

  1. // © Copyright 1994 Apple Computer, Inc, All Rights Reserved
  2.  
  3. // Basic constants that we may or may not need
  4. constant kAppName     := '|SerialEx:PIEDTS|;
  5. constant kAppSymbol    := '|SerialEx:PIEDTS|;
  6.  
  7.  
  8. // This is our protoEndpoint specification. Note we are
  9. // using DefConst so the symbol is known as a constant when
  10. // we compile the proto, and later use it during runtime.
  11.  
  12. DefConst('protoLlamaPEndpoint, {
  13. // basic endpoint proto
  14.     _proto: protoEndpoint,
  15.  
  16. // Options (array stored inside the configOptions slot.
  17.     configOptions: [
  18.         // basic serial port
  19.         { label: kCMSAsyncSerial, type: 'service, opCode: opSetRequired },
  20.         // basic serial port options
  21.       { label: kCMOSerialIOParms, type: 'option, opCode: opSetNegotiate,
  22.         data: { bps: k9600bps, dataBits: k8DataBits, stopBits: k1StopBits, 
  23.           parity: kNoParity } },
  24.         // flow control (XON/XOFF)
  25.       { label: kCMOInputFlowControlParms, type: 'option, opCode: opSetNegotiate,
  26.         data: { xonChar: unicodeDC1, xoffChar: unicodeDC3, useSoftFlowControl: true, 
  27.         useHardFlowControl: nil } },
  28.    ],
  29.  
  30. //    Our exception handler (asynch exceptions from the endpoint).
  31.     exceptionHandler: func(exception)
  32.     begin
  33.         print("Got the exception from Abort, ignoring it for the time being");
  34.     end,
  35.  
  36. // Our state machines:
  37. // WaitForAck, main dispatcher, waits for the first ACK from the other side.
  38.    waitForACK:
  39.    {
  40.         InputForm: 'string,
  41.         endCharacter: $?,             // ACK? expected
  42.        discardAfter: 200,            // scan buffer size
  43.        
  44.         InputScript: func(endpoint, s)
  45.        begin
  46.            if (StrPos(s, "ACK?", 0)) then    // send response (help instructions in this case)
  47.           begin
  48.              endpoint:Output("Send any of the following commands:" & unicodeCR &
  49.                                         unicodeLF, nil);  
  50.                 endpoint:Output("PLAY! -- will play a tone on the Newton" & unicodeCR &
  51.                                         unicodeLF, nil);
  52.                 endpoint:Output("Add more comments if more functions...." & unicodeCR &
  53.                                         unicodeLF, nil);
  54.              endpoint:FlushOutput();
  55.              endpoint:SetInputSpec(endpoint.waitForFUNCTION); // the main dispatch loop
  56.              end
  57.    end,
  58.    },
  59.  
  60.  
  61.     // This is the generic dispatcher state, send something ending with ! and
  62.    // the Newton will serve.
  63.     waitForFUNCTION:
  64.     {
  65.         InputForm: 'string,
  66.       endCharacter: $!,          // expects a '!' as part of the command
  67.        discardAfter: 200,            // scan buffer size
  68.  
  69.       InputScript: func(endpoint, s)
  70.       begin
  71.               if(StrPos(s, "PLAY!", 0)) then      // play function
  72.             begin
  73.                 PlaySound(ROM_funbeep);
  74.                endpoint:Output(unicodeCR, nil);
  75.                endpoint:Output(unicodeLF, nil);
  76.                endpoint:FlushOutput();
  77.             end;
  78.        end;
  79.     }, 
  80. });
  81.  
  82.  
  83. // ---- End Project Data ----
  84.  
  85.  
  86. // ---- File baseView.t ----
  87. baseView :=
  88.    {title: "Serial Example 1.0",
  89.     viewBounds: {left: 0, top: 2, right: 236, bottom: 334},
  90.     viewFormat: 83951953
  91.     ,
  92.     viewSetupFormScript:
  93.       func()
  94.       begin
  95.       // Make sure the screen is adjusted to MP and MP110.
  96.           constant kMaxAppWidth := 240 ; // original MP width
  97.           constant kMaxAppHeight:= 336 ; // original MP height
  98.       
  99.           local b := GetAppParams() ;
  100.       
  101.       // Make view no bigger than the original MP.
  102.           viewBounds := RelBounds(b.appAreaLeft, b.appAreaTop,
  103.                               MIN(b.appAreaWidth, kMaxAppWidth),
  104.                               MIN(b.appAreaHeight, kMaxAppHeight));
  105.       end,
  106.     ep: nil,
  107.     DisposeEndpointScript:
  108.       // Dispose our endpoint gracefully
  109.       func()
  110.       begin
  111.           :DisplayInfo("About to flush...");
  112.           ep:FlushInput ();
  113.           ep:FlushOutput ();
  114.       
  115.           :DisplayInfo("Flush OK, now zap inputspecs");
  116.          ep.nextInputSpec := nil;
  117.           ep:SetInputSpec(nil);
  118.       
  119.           :DisplayInfo("InputSpec handling OK, now Abort");
  120.           ep:Abort();
  121.           :DisplayInfo("Abort OK, now delayed action later...");
  122.       
  123.           AddDelayedAction(func() begin
  124.         // let the endpoint clean up from the abort before disconnecting and disposing
  125.                 ep:Disconnect();
  126.               ep:Dispose();
  127.               ep := nil;
  128.             end,
  129.             [], 1000);
  130.       
  131.           
  132.       end,
  133.     viewQuitScript:
  134.       func()
  135.       begin
  136.           if ep <> nil then
  137.               :DisposeEndpointScript();            // get rid of any active endpoints
  138.       end,
  139.     displayInfo:
  140.       func(string)
  141.       begin
  142.           SetValue(infoView, 'text, string);
  143.       end,
  144.     _proto: protoApp,
  145.     debug: "baseView"
  146.    };
  147.  
  148. ConnectButton := /* child of baseView */
  149.    {text: "Connect",
  150.     buttonClickScript:
  151.       // Make the initial connection and start listening/sending.
  152.       func()
  153.       begin
  154.           local anErr := nil;
  155.       
  156.           if commState = 'Disconnected then        // create a new connectioin
  157.               :ConnectScript();
  158.       
  159.           else if commState = 'Connected then        // we want to disconnect the connection
  160.           begin
  161.               :DisconnectScript();
  162.           end;    
  163.       end,
  164.     viewBounds: {left: 66, top: 218, right: 158, bottom: 238},
  165.     commState:
  166.       // this keeps track of our current communication state
  167.       'Disconnected,
  168.     ConnectScript:
  169.       func()
  170.       begin
  171.           // Create an endpoint for our use, protoLlamaPEndpoint is 
  172.           // defined inside the Project Data file.
  173.               ep := {_proto: protoLlamaPEndpoint, _parent: self};
  174.       
  175.           // We added the parent slot for parent inheritance inside
  176.           // the endpoint frame.
  177.       
  178.               if ep = nil then
  179.                   :Notify(kNotifyAlert, EnsureInternal("SerialEx"),
  180.                       EnsureInternal("Could not create an endpoint in RAM"));
  181.               else
  182.                   :DisplayInfo("Created an endpoint in RAM");
  183.       
  184.               :DisplayInfo("About to Instantiate");
  185.           // Initialize the endpoint.
  186.               anErr := ep:Instantiate(ep, nil);    
  187.       
  188.               if anErr then
  189.               begin
  190.                   :Notify(kNotifyAlert, EnsureInternal("SerialEx"), 
  191.                       EnsureInternal("Sorry, serial port in use!"));
  192.                   return;
  193.               end;
  194.               else
  195.                   :DisplayInfo("Initialized the endpoint.");
  196.       
  197.           // Do a Connect.
  198.               anErr := ep:Connect(nil,nil);
  199.       
  200.               if anErr then
  201.               begin
  202.                   :Notify(kNotifyAlert, EnsureInternal("SerialEx"),
  203.                       EnsureInternal("Couldn't connect, check cable and other end!"));
  204.                   return;
  205.               end;
  206.               else
  207.                   :DisplayInfo("Connected to the other side.");
  208.           
  209.           // Set the Next Input Specification.
  210.               ep:SetInputSpec(ep.waitForACK);
  211.       
  212.           // We are using one single button, so change the text to disconnect
  213.               SetValue(self, 'text, "Disconnect");
  214.               commState := 'Connected;
  215.       end,
  216.     DisconnectScript:
  217.       func()
  218.       begin
  219.           :DisposeEndpointScript();
  220.       
  221.       // We are using one single button, so change the text to Connect
  222.               SetValue(self, 'text, "Connect");
  223.               commState := 'Disconnected;
  224.       end,
  225.     _proto: protoTextButton,
  226.     debug: "ConnectButton"
  227.    };
  228.  
  229.  
  230.  
  231. infoView := /* child of baseView */
  232.    {text: "Information View",
  233.     viewBounds: {left: 16, top: 24, right: 224, bottom: 176},
  234.     viewJustify: 0,
  235.     viewFormat: 67109200,
  236.     _proto: protoStaticText,
  237.     debug: "infoView"
  238.    };
  239. // View infoView is declared to baseView
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247. // ---- Beginning of section for non used Layout files ----
  248.  
  249. // End of output